package com.file.manage.infrastructure.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.file.manage.infrastructure.base.dto.base.BaseTreeDTO;
import com.file.manage.infrastructure.base.entiry.BaseEntity;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: hsy
 * @date: 2023/4/25 17:30
 * @description:
 */
public class TreeUtil {

    /**
     * 目录数据封装为树型结构
     *
     * @param list
     */
    public static <T extends BaseTreeDTO<T>> List<T> getDirectoryTreeData(List<T> list, String rootId) {
        List<T> rootList = new ArrayList<>();
        // 根目录
        if (CollectionUtil.isEmpty(list)) {
            return rootList;
        }
        // 子目录
        ListMultimap<String, T> parentId2SubMap = ArrayListMultimap.create();
        for (T dto : list) {
            String parentId = dto.getParentId();
            if ((StrUtil.isBlank(rootId) && StrUtil.isBlank(parentId)) || StrUtil.equals(dto.getId(), rootId)) {
                rootList.add(dto);
            } else {
                parentId2SubMap.put(parentId, dto);
            }
        }
        dataConvertToTree(rootList, parentId2SubMap);
        return rootList;
    }

    /**
     * 目录数据封装为树型结构
     *
     * @param list
     */
    public static <M extends BaseTreeDTO<M>, T extends BaseEntity<T>> List<M> getDirectoryTreeData(List<T> list, Class<M> mClass, String rootId) {
        List<M> rootList = new ArrayList<>();
        // 根目录
        if (CollectionUtil.isEmpty(list)) {
            return rootList;
        }
        List<M> l = ConvertUtil.convertList(list, mClass);
        // 子目录
        ListMultimap<String, M> parentId2SubMap = ArrayListMultimap.create();
        for (M dto : l) {
            String parentId = dto.getParentId();
            if ((StrUtil.isBlank(rootId) && StrUtil.isBlank(parentId)) || StrUtil.equals(dto.getId(), rootId)) {
                rootList.add(dto);
            } else {
                parentId2SubMap.put(parentId, dto);
            }
        }
        dataConvertToTree(rootList, parentId2SubMap);
        return rootList;
    }

    /**
     * 目录数据封装为树型结构
     *
     * @param list
     */
    public static <M extends BaseTreeDTO<M>, T extends BaseEntity<T>> List<M> getDirectoryTreeData(List<T> list, Class<M> mClass) {
        return getDirectoryTreeData(list, mClass, null);
    }

    public static <T extends BaseTreeDTO<T>> List<T> tree2List(List<T> list, boolean hasChild) {
        List<T> res = new ArrayList<>();
        if (CollUtil.isEmpty(list)) return res;
        for (T t : list) {
            res.add(t);
            if (CollUtil.isNotEmpty(t.getChildren())) {
                res.addAll(tree2List(t.getChildren()));
                if (!hasChild) t.setChildren(null);
            }
        }
        return res;
    }

    public static <T extends BaseTreeDTO<T>> List<T> tree2List(List<T> list) {
        return tree2List(list, false);
    }

    private static <T extends BaseTreeDTO<T>> void dataConvertToTree(List<T> rootList, ListMultimap<String, T> parentId2SubMap) {
        if (CollectionUtil.isEmpty(rootList)) {
            return;
        }
        for (T directoryDTO : rootList) {
            List<T> l = parentId2SubMap.get(directoryDTO.getId());
            if (CollectionUtil.isEmpty(l)) {
                continue;
            }
            dataConvertToTree(l, parentId2SubMap);
            directoryDTO.setChildren(l);
        }
    }
}

